package com.lifeverse.repository;

import com.lifeverse.entity.Decision;
import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.Resource;
import com.lifeverse.entity.ResourceAllocation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 资源分配数据访问接口
 */
@Repository
public interface ResourceAllocationRepository extends JpaRepository<ResourceAllocation, Long> {
    
    /**
     * 根据资源查找分配记录
     */
    List<ResourceAllocation> findByResource(Resource resource);
    
    /**
     * 根据分配对象查找分配记录
     */
    List<ResourceAllocation> findByAllocatedTo(LifeEntity allocatedTo);
    
    /**
     * 根据决策查找分配记录
     */
    List<ResourceAllocation> findByDecision(Decision decision);
    
    /**
     * 根据分配状态查找分配记录
     */
    List<ResourceAllocation> findByAllocationStatus(String allocationStatus);
    
    /**
     * 根据资源和分配对象查找分配记录
     */
    List<ResourceAllocation> findByResourceAndAllocatedTo(Resource resource, LifeEntity allocatedTo);
    
    /**
     * 根据资源和状态查找分配记录
     */
    List<ResourceAllocation> findByResourceAndAllocationStatus(Resource resource, String allocationStatus);
    
    /**
     * 根据分配对象和状态查找分配记录
     */
    List<ResourceAllocation> findByAllocatedToAndAllocationStatus(LifeEntity allocatedTo, String allocationStatus);
    
    /**
     * 查找活跃的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.allocationStatus IN :activeStatuses")
    List<ResourceAllocation> findActiveAllocations(@Param("activeStatuses") List<String> activeStatuses);
    
    /**
     * 根据资源查找活跃的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.resource = :resource AND ra.allocationStatus IN :activeStatuses")
    List<ResourceAllocation> findActiveAllocationsByResource(@Param("resource") Resource resource,
                                                           @Param("activeStatuses") List<String> activeStatuses);
    
    /**
     * 根据分配对象查找活跃的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.allocatedTo = :allocatedTo AND ra.allocationStatus IN :activeStatuses")
    List<ResourceAllocation> findActiveAllocationsByAllocatedTo(@Param("allocatedTo") LifeEntity allocatedTo,
                                                              @Param("activeStatuses") List<String> activeStatuses);
    
    /**
     * 查找过期的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.plannedReleaseAt IS NOT NULL AND ra.plannedReleaseAt < :now AND ra.actualReleaseAt IS NULL")
    List<ResourceAllocation> findExpiredAllocations(@Param("now") LocalDateTime now);
    
    /**
     * 查找长时间运行的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.startedAt IS NOT NULL AND ra.startedAt < :threshold AND ra.endedAt IS NULL")
    List<ResourceAllocation> findLongRunningAllocations(@Param("threshold") LocalDateTime threshold);
    
    /**
     * 根据时间范围查找分配记录
     */
    List<ResourceAllocation> findByAllocatedAtBetween(LocalDateTime startTime, LocalDateTime endTime);
    
    /**
     * 根据优先级排序查找分配记录
     */
    List<ResourceAllocation> findByResourceOrderByPriorityDesc(Resource resource);
    
    /**
     * 分页查找资源的分配记录
     */
    Page<ResourceAllocation> findByResource(Resource resource, Pageable pageable);
    
    /**
     * 分页查找分配对象的分配记录
     */
    Page<ResourceAllocation> findByAllocatedTo(LifeEntity allocatedTo, Pageable pageable);
    
    /**
     * 统计资源的分配次数
     */
    long countByResource(Resource resource);
    
    /**
     * 统计分配对象的分配次数
     */
    long countByAllocatedTo(LifeEntity allocatedTo);
    
    /**
     * 统计特定状态的分配数量
     */
    long countByAllocationStatus(String allocationStatus);
    
    /**
     * 计算资源的总分配量
     */
    @Query("SELECT SUM(ra.allocatedAmount) FROM ResourceAllocation ra WHERE ra.resource = :resource")
    BigDecimal sumAllocatedAmountByResource(@Param("resource") Resource resource);
    
    /**
     * 计算资源的总使用量
     */
    @Query("SELECT SUM(ra.usedAmount) FROM ResourceAllocation ra WHERE ra.resource = :resource")
    BigDecimal sumUsedAmountByResource(@Param("resource") Resource resource);
    
    /**
     * 计算分配对象的总分配量
     */
    @Query("SELECT SUM(ra.allocatedAmount) FROM ResourceAllocation ra WHERE ra.allocatedTo = :allocatedTo")
    BigDecimal sumAllocatedAmountByAllocatedTo(@Param("allocatedTo") LifeEntity allocatedTo);
    
    /**
     * 计算分配对象的总使用量
     */
    @Query("SELECT SUM(ra.usedAmount) FROM ResourceAllocation ra WHERE ra.allocatedTo = :allocatedTo")
    BigDecimal sumUsedAmountByAllocatedTo(@Param("allocatedTo") LifeEntity allocatedTo);
    
    /**
     * 查找高使用率的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE (ra.usedAmount / ra.allocatedAmount) >= :usageThreshold")
    List<ResourceAllocation> findHighUsageAllocations(@Param("usageThreshold") BigDecimal usageThreshold);
    
    /**
     * 查找低使用率的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE (ra.usedAmount / ra.allocatedAmount) <= :usageThreshold")
    List<ResourceAllocation> findLowUsageAllocations(@Param("usageThreshold") BigDecimal usageThreshold);
    
    /**
     * 查找高效率的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.efficiencyScore >= :efficiencyThreshold")
    List<ResourceAllocation> findHighEfficiencyAllocations(@Param("efficiencyThreshold") BigDecimal efficiencyThreshold);
    
    /**
     * 查找低效率的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.efficiencyScore <= :efficiencyThreshold")
    List<ResourceAllocation> findLowEfficiencyAllocations(@Param("efficiencyThreshold") BigDecimal efficiencyThreshold);
    
    /**
     * 查找成本最高的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra ORDER BY ra.allocationCost DESC")
    List<ResourceAllocation> findHighestCostAllocations(Pageable pageable);
    
    /**
     * 查找最近的分配记录
     */
    List<ResourceAllocation> findTop10ByOrderByAllocatedAtDesc();
    
    /**
     * 查找最近完成的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.endedAt IS NOT NULL ORDER BY ra.endedAt DESC")
    List<ResourceAllocation> findRecentlyCompletedAllocations(Pageable pageable);
    
    /**
     * 根据关键词搜索分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.allocationReason LIKE %:keyword% OR ra.tags LIKE %:keyword%")
    List<ResourceAllocation> findByKeyword(@Param("keyword") String keyword);
    
    /**
     * 查找即将到期的分配记录
     */
    @Query("SELECT ra FROM ResourceAllocation ra WHERE ra.plannedReleaseAt IS NOT NULL AND ra.plannedReleaseAt BETWEEN :now AND :threshold AND ra.actualReleaseAt IS NULL")
    List<ResourceAllocation> findAllocationsExpiringBetween(@Param("now") LocalDateTime now, @Param("threshold") LocalDateTime threshold);
}